use std::{collections::HashMap, sync::Arc};

use monitor::{CompleterSuggestion, Monitor, MonitorCommand};

use super::mon_command_completer;
use crate::{DfsError, DfsOpenOptions, DfsResult};

struct EchoCommand;

impl EchoCommand {
    fn do_echo(&self, args: &HashMap<String, String>) -> DfsResult<()> {
        let arg = args.get("args").unwrap();
        let pot = args.get("pot").unwrap();
        let file = args.get("file").unwrap();

        let seek = pot == ">>";
        if pot != ">" && !seek {
            return Err(DfsError::InvalidArgs);
        }

        let fd = DfsOpenOptions::new().write(true).seek(seek).open(file)?;
        if pot == ">>" {
            fd.seek(crate::DSeekFrom::End(0))?;
        }
        fd.write(arg)?;
        Ok(())
    }
}

impl MonitorCommand for EchoCommand {
    fn mon_protocol_exec(&self, args: &monitor::Protocol) -> DfsResult<monitor::Protocol> {
        self.do_echo(args)?;
        Ok(HashMap::new())
    }

    fn mon_readline_arg_type(&self) -> Option<&'static str> {
        Some("args:*,pot:*,file:*")
    }

    fn mon_readline_completer(&self, args: &[&str], is_space: bool) -> Option<CompleterSuggestion> {
        mon_command_completer(args.last(), false, is_space)
    }

    fn mon_readline_exec(
        &self,
        args: &HashMap<String, String>,
        _: &monitor::MonitorPrinter,
    ) -> DfsResult<()> {
        self.do_echo(args)
    }

    fn mon_readline_help(&self) -> String {
        String::from("将参数写到文件中")
    }

    fn mon_readline_long_help(&self) -> Option<String> {
        Some(String::from("用法: echo <参数> >|>> <文件>"))
    }
}

pub(crate) fn monitor_command_echo_register(mon: &Monitor) {
    mon.register_command("echo", Arc::new(EchoCommand)).unwrap();
}
